package com.study.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.study.dao.CommonDao;
import com.study.pojo.*;
import com.study.service.UserService;
import com.study.service.WeChatService;
import com.study.util.MyConvert;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigDecimal;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class WeChatServiceImpl implements WeChatService {
    @Resource
    private UserService userService;
    @Resource
    private CommonDao commonDao;
    private RestTemplate restTemplate = new RestTemplate();

    @Override
    public String getToken(String type) {
        return null;
    }

    @Override
    public String getXml(String type, RequestMessage requestMessage) {
        String resultXml;
        switch (type) {
            case "text":
                resultXml=getTextMessage(requestMessage);
                break;
            case "image":
                resultXml=getImageMessage(requestMessage);
                break;
            case "voice":
                resultXml=getVoiceMessage(requestMessage);
                break;
            case "video":
                resultXml=getVideoMessage(requestMessage);
                break;
            case "shortvideo":
                resultXml=getShortVideoMessage(requestMessage);
                break;
            case "location":
                resultXml=getLocationMessage(requestMessage);
                break;
            case "link":
                resultXml=getLinkMessage(requestMessage);
                break;
            case "event":
                resultXml=getEventMessage(requestMessage);
                break;
            default:
                resultXml="";
                break;
        }
        return resultXml;
    }

    @Override
    public String getJson(String type) {
        return null;
    }

    @Override
    public ResponseResult getOpenId(String code) {
        ResponseResult responseResult=new ResponseResult();
        responseResult.setCode(500);
        responseResult.setMessage("获取openId失败");
        String appId= "wx1abc1bf0aa1209dc";
        String appSecret= "dea99123bf69b1174507110649a2b549";
        String url= "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";
        url=String.format(url,appId,appSecret,code);
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/x-www-form-urlencoded; charset=UTF-8");
        headers.setContentType(type);
        headers.set(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);
        headers.set(HttpHeaders.ACCEPT_CHARSET, StandardCharsets.UTF_8.toString());

        URI uri = URI.create(url);
        String res = restTemplate.getForObject(uri,String.class);
        if(!StringUtils.isEmpty(res)) {
            try {
                ObjectMapper objectMapper = new ObjectMapper();
                HashMap map = objectMapper.readValue(res, HashMap.class);
                System.out.println(map);
                responseResult.setCode(200);
                responseResult.setData(map);
                responseResult.setMessage("");
                return responseResult;
            }catch (Exception ex){
                ex.printStackTrace();
            }
        }
        return responseResult;
    }

    @Override
    public ResponseResult getUserInfo(String openId) {
        ResponseResult result=new ResponseResult();
        User user =userService.selectByOpenId(openId);
        if(user==null){
            user=new User();
        }
        if(StringUtils.isEmpty(user.getOpenId())){
            user.setOpenId(openId);
            userService.save(user);
        }
        Map<String,Object> data=new HashMap<>();
        data.put("user",user);
        result.setData(data);
        result.setCode(200);
        return result;
    }

    @Override
    public ResponseResult getMainData(Map<String, Object> params) {
        return getHomeData(params);
    }

    @Override
    public ResponseResult getHistoryData(Map<String, Object> params) {
        return getHistoryRecord(params);
    }

    @Override
    public ResponseResult getMainImages(Map<String, Object> params) {
        return null;
    }

    @Override
    public ResponseResult getTodayWeight(Map<String, Object> params) {
        ResponseResult result=new ResponseResult();
        result.setCode(200);
        if(params.get("date")==null||StringUtils.isEmpty(params.get("date").toString())){
            params.put("date",LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        }
        Map<String,Object> weight=commonDao.selectTodayWeight(params);
        Map<String,Object> data=new HashMap<>();
        if(weight!=null) {
            data.put("id",weight.get("id"));
            data.put("am",weight.get("morning_weight"));
            data.put("pm",weight.get("afternoon_weight"));
            data.put("date",params.get("date"));
        }else {
            data.put("id",null);
            data.put("am",null);
            data.put("pm",null);
            data.put("date",LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        }
        result.setData(data);
        return result;
    }

    @Override
    public ResponseResult saveWeight(Map<String, Object> params) {
        ResponseResult result=new ResponseResult();
        result.setCode(200);
        User user=userService.selectByOpenId(params.get("openId").toString());
        Map<String,Object> fields=new HashMap<>();
        fields.put("morning_weight",params.get("amWeight"));
        fields.put("afternoon_weight",params.get("pmWeight"));
        fields.put("user_id",user.getId());
        LocalDate date=LocalDate.now();
        if(params.get("date")!=null && !StringUtils.isEmpty(params.get("date").toString())){
            date=LocalDate.parse(params.get("date").toString(),DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        }
        Map<String,Object> filter=new HashMap<>();
        filter.put("date",date);
        filter.put("openId",params.get("openId"));
        Map<String,Object> weight=commonDao.selectTodayWeight(filter);
        int count;
        if(weight==null || weight.get("id")==null||StringUtils.isEmpty(weight.get("id").toString())){
            fields.put("date",date);
            count = commonDao.insertSelective("weight_record",fields);
        }else {
            fields.put("id",weight.get("id"));
            fields.put("date",date);
            fields.put("last_update_date",LocalDateTime.now(ZoneOffset.of("+8")));
            count = commonDao.updateByPrimaryKeySelective("weight_record",fields);
        }
        if(count<=0){
            result.setCode(500);
            result.setMessage("保存失败");
        }
        return result;
    }
    @Override
    public ResponseResult getSportsData(Map<String,Object> params){
        ResponseResult result=new ResponseResult();
        result.setCode(200);
        String encryptedText=params.get("encryptedData").toString();
        String key=params.get("sessionKey").toString();
        String iv=params.get("iv").toString();
        String rawString=decrypt(encryptedText,key,iv);
        ObjectMapper objectMapper=new ObjectMapper();
        try{
            HashMap map = objectMapper.readValue(rawString,HashMap.class);
//            map.forEach((k,v)->{
//                if(v instanceof ArrayList){
//                    ((ArrayList)v).forEach(it->{
//                        if(it instanceof HashMap){
//                            Object stamp=((HashMap)it).get("timestamp");
//                            if(stamp instanceof Integer) {
//                                LocalDateTime dateTime = LocalDateTime.ofEpochSecond(((Integer) stamp).longValue(),0, ZoneOffset.ofHours(8));
//                                ((HashMap) it).put("datetime", dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
//                            }
//                        }
//                    });
//                }
//            });
            ArrayList<Map<String,Object>> list=(ArrayList<Map<String,Object>>) map.get("stepInfoList");
            Map<String,Object> data=new HashMap<>();
            ArrayList<Object> sports=new ArrayList<>();
            sports.add(list.get(list.size()-1).get("step"));
            sports.add(list.get(list.size()-2).get("step"));
            data.put("sports",sports);
            result.setData(data);
            System.out.println(map);
        }catch (Exception ex){
            ex.printStackTrace();
        }
        //LocalDateTime dateTime =LocalDateTime.ofEpochSecond(remindTime,0, ZoneOffset.ofHours(8));
        System.out.println(rawString);
        return result;
    }

    @Override
    public ResponseResult getFirstChartData(Map<String, Object> params) {
        return getFirstData(params);
    }

    @Override
    public ResponseResult getSecondChartData(Map<String, Object> params) {
        return getSecondData(params);
    }

    @Override
    public ResponseResult getThirdChartData(Map<String, Object> params) {
        return null;
    }

    private ResponseResult getFirstData(Map<String,Object> params){
        params.put("date",LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        Map<String,Object> todayWeight=commonDao.selectTodayWeight(params);
        String morningWeight="0";
        if(todayWeight!=null&&todayWeight.get("morning_weight")!=null){
            BigDecimal weight=(BigDecimal) todayWeight.get("morning_weight");
            DecimalFormat format = new DecimalFormat("0.##");
            morningWeight=format.format(weight);
        }
        ResponseResult result=new ResponseResult();
        Map<String,Object> option=new HashMap<>();
        ArrayList<Object> series=new ArrayList<>();
        Map<String,Object> gauge=new HashMap<>();
        gauge.put("name","上午体重");
        gauge.put("type","gauge");
        Map<String,Object> detail=new HashMap<>();
        detail.put("fontSize",10);
        detail.put("formatter","{value}kg");
        gauge.put("detail",detail);
        Map<String,Object> axisLine=new HashMap<>();
        axisLine.put("show",true);
        Map<String,Object> lineStyle=new HashMap<>();
        lineStyle.put("width",20);
        lineStyle.put("shadowBlur",0);
        ArrayList<Object> color=new ArrayList<>();
        ArrayList<Object> c1=new ArrayList<>();
        c1.add(0.4);
        c1.add("#67e0e3");
        color.add(c1);
        ArrayList<Object> c2=new ArrayList<>();
        c2.add(0.6);
        c2.add("#37a2da");
        color.add(c2);
        ArrayList<Object> c3=new ArrayList<>();
        c3.add(1);
        c3.add("#fd666d");
        color.add(c3);
        lineStyle.put("color",color);
        axisLine.put("lineStyle",lineStyle);
        gauge.put("axisLine",axisLine);
        Map<String,Object> axisLabel=new HashMap<>();
        axisLabel.put("distance",1);
        gauge.put("axisLabel",axisLabel);
        ArrayList<Object> data =new ArrayList<>();
        Map<String,Object> dataItem=new HashMap<>();
        dataItem.put("name","上午");
        dataItem.put("value",morningWeight);
        data.add(dataItem);
        gauge.put("data",data);
        series.add(gauge);
        option.put("series",series);
        result.setCode(200);
        result.setData(option);
        return result;
        /**
         * option = {
         *     series : [
         *     {
         *       name: '上午体重',
         *       type: 'gauge',
         *       detail: {
         *         formatter: '{value}kg'
         *       },
         *       axisLine: {
         *         show: true,
         *         lineStyle: {
         *           width: 30,
         *           shadowBlur: 0,
         *           color: [
         *             [0.4, '#67e0e3'],
         *             [0.6, '#37a2da'],
         *             [1, '#fd666d']
         *           ]
         *         }
         *       },
         *       data: [{
         *         value: 70,
         *         name: '上午',
         *       }]
         *
         *     }]
         * };
         */
    }

    private ResponseResult getSecondData(Map<String,Object> params){
        List<Map<String,Object>> severalWeigth=commonDao.selectTopDayWeight(params);
//            map.forEach((k,v)->{
//                if(v instanceof ArrayList){
//                    ((ArrayList)v).forEach(it->{
//                        if(it instanceof HashMap){
//                            Object stamp=((HashMap)it).get("timestamp");
//                            if(stamp instanceof Integer) {
//                                LocalDateTime dateTime = LocalDateTime.ofEpochSecond(((Integer) stamp).longValue(),0, ZoneOffset.ofHours(8));
//                                ((HashMap) it).put("datetime", dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
//                            }
//                        }
//                    });
//                }
//            });
        severalWeigth.sort(Comparator.comparing(a -> (Date) a.get("date")));
        DateTimeFormatter formatter=DateTimeFormatter.ofPattern("MM-dd");
        List<String> xData= severalWeigth.stream().map(it->{
            String dataString;
            if(it.get("date") instanceof Date){
                LocalDateTime time = ((Date)it.get("date")).toInstant().atOffset(ZoneOffset.of("+8")).toLocalDateTime();
                dataString = time.format(formatter);
            }else {
                dataString =((LocalDateTime)it.get("date")).format(formatter);
            }
            return dataString;
        }).collect(Collectors.toList());
        List<BigDecimal> yData= severalWeigth.stream().map(it->{
            BigDecimal weight=BigDecimal.valueOf(0);
            if(it.get("morning_weight") != null){
                weight=(BigDecimal)it.get("morning_weight");
            }
            return weight;
        }).collect(Collectors.toList());
        List<BigDecimal> yDataPm= severalWeigth.stream().map(it->{
            BigDecimal weight=BigDecimal.valueOf(0);
            if(it.get("afternoon_weight") != null){
                weight=(BigDecimal)it.get("afternoon_weight");
            }
            return weight;
        }).collect(Collectors.toList());
        BigDecimal maxValue=yData.stream().max(Comparator.naturalOrder()).orElse(new BigDecimal(0));
        BigDecimal maxValuePm=yDataPm.stream().max(Comparator.naturalOrder()).orElse(new BigDecimal(0));
        maxValue = maxValue.compareTo(maxValuePm)>0?maxValue:maxValuePm;
        BigDecimal minValue=yData.stream().filter(it->BigDecimal.valueOf(0).compareTo(it)<0).min(Comparator.naturalOrder()).orElse(new BigDecimal(0));
        BigDecimal minValuePm=yDataPm.stream().filter(it->BigDecimal.valueOf(0).compareTo(it)<0).min(Comparator.naturalOrder()).orElse(new BigDecimal(0));
        minValue=minValue.compareTo(minValuePm)>0?minValuePm:minValue;
        Map<String,List<BigDecimal>> seriesData=new HashMap<>();
        seriesData.put("上午",yData);
        seriesData.put("下午",yDataPm);

        ResponseResult result=new ResponseResult();
        Map<String,Object> option=new HashMap<>();
        Map<String,Object> title=new HashMap<>();
        title.put("text","体重趋势");
        option.put("title",title);
        Map<String,Object> tooltip=new HashMap<>();
        tooltip.put("show",false);
        option.put("tooltip",tooltip);
        Map<String,Object> legend=new HashMap<>();
        legend.put("left","right");
        option.put("legend",legend);
        HashMap<String,Object> grid=new HashMap<>();
        grid.put("left","55");
        grid.put("right","40");
        option.put("grid",grid);
        Map<String,Object> toolbox=new HashMap<>();
        toolbox.put("show",false);
        Map<String,Object> feature=new HashMap<>();
        Map<String,Object> dataZoom=new HashMap<>();
        dataZoom.put("yAxisIndex","none");
        feature.put("dataZoom",dataZoom);
        Map<String,Object> dataView=new HashMap<>();
        dataView.put("readOnly",false);
        feature.put("dataView",dataView);
        Map<String,Object> magicType =new HashMap<>();
        ArrayList<Object> mType=new ArrayList<>();
        mType.add("line");
        mType.add("bar");
        magicType.put("type",mType);
        feature.put("magicType",magicType);
        Map<String,Object> restore=new HashMap<>();
        feature.put("restore",restore);
        Map<String,Object> saveAsImage=new HashMap<>();
        feature.put("saveAsImage",saveAsImage);
        toolbox.put("feature",feature);
        option.put("toolbox",toolbox);
        Map<String,Object> xAxis=new HashMap<>();
        xAxis.put("type","category");
        Map<String,Object> axisTick=new HashMap<>();
        axisTick.put("show",true);
        axisTick.put("alignWithLabel",true);
        xAxis.put("axisTick",axisTick);
        xAxis.put("boundaryGap",true);
        List<String> xAxisData=xData;
//        xAxisData.add("3-12");
//        xAxisData.add("3-13");
//        xAxisData.add("3-14");
//        xAxisData.add("3-15");
        xAxis.put("data",xAxisData);
        option.put("xAxis",xAxis);
        Map<String,Object> yAxis=new HashMap<>();
        yAxis.put("type","value");
        yAxis.put("min",minValue.intValue()==0?40:minValue.intValue()-1);
        yAxis.put("max",maxValue.intValue()==0?70:maxValue.intValue()+1);
        Map<String,Object> axisLabel=new HashMap<>();
        axisLabel.put("formatter","{value}kg");
        yAxis.put("axisLabel",axisLabel);
        option.put("yAxis",yAxis);
        //图例
        ArrayList<Object> legendData=new ArrayList<>();
        //legendData.add("上午");
        //数据系列
        ArrayList<Object> series=new ArrayList<>();

        for (Map.Entry<String, List<BigDecimal>> entry : seriesData.entrySet()) {
            legendData.add(entry.getKey());

            Map<String,Object> seriesOne=new HashMap<>();
            seriesOne.put("name",entry.getKey());
            seriesOne.put("type","line");
            seriesOne.put("smooth",false);//平滑曲线
            Map<String,Object> seriesOneLabel=new HashMap<>();
            seriesOneLabel.put("show",true);
            seriesOneLabel.put("position","下午".equals(entry.getKey())?"top":"bottom");
            seriesOne.put("label",seriesOneLabel);
            List<BigDecimal> oneData=entry.getValue();
            seriesOne.put("data",oneData);
            Map<String,Object> markPoint=new HashMap<>();
            markPoint.put("symbol","none");
            ArrayList<Object> markPointData=new ArrayList<>();
            Map<String,Object> pointOne=new HashMap<>();
            pointOne.put("type","max");
            pointOne.put("name","最大值");
            markPointData.add(pointOne);
            Map<String,Object> pointTwo=new HashMap<>();
            pointTwo.put("type","min");
            pointTwo.put("name","最小值");
            markPointData.add(pointTwo);
            markPoint.put("data",markPointData);
            seriesOne.put("markPoint",markPoint);
            Map<String,Object> markLine=new HashMap<>();
            ArrayList<Object> markLineData=new ArrayList<>();
            Map<String,Object> lineDataOne=new HashMap<>();
            lineDataOne.put("type","average");
            lineDataOne.put("name","平均值");
            //markLineData.add(lineDataOne);
            markLine.put("data",markLineData);
            seriesOne.put("markLine",markLine);
            series.add(seriesOne);
        }
        legend.put("data",legendData);
        option.put("series",series);
        result.setCode(200);
        result.setData(option);
        /**
         * var option = {
         *             title: {
         *                 text: 'ECharts 入门示例'
         *             },
         *             tooltip: {},
         *             legend: {
         *                 data:['销量']
         *             },
         *             toolbox: {
         *                 show: true,
         *                 feature: {
         *                     dataZoom: {
         *                         yAxisIndex: 'none'
         *                     },
         *                     dataView: {readOnly: false},
         *                     magicType: {type: ['line', 'bar']},
         *                     restore: {},
         *                     saveAsImage: {}
         *                 }
         *             },
         *             xAxis: {
         *                 type: 'category',
         *                 boundaryGap: false,
         *                 data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
         *             },
         *             yAxis: {
         *                 type: 'value',
         *                 axisLabel: {
         *                     formatter: '{value} °C'
         *                 }
         *             },
         *             series: [{
         *                 name: '销量',
         *                 type: 'bar',
         *                 data: [5, 20, 36, 10, 10, 20]
         *                 markPoint: {
         *                     data: [
         *                         {type: 'max', name: '最大值'},
         *                         {type: 'min', name: '最小值'}
         *                     ]
         *                 },
         *                 markLine: {
         *                     data: [
         *                         {type: 'average', name: '平均值'}
         *                     ]
         *                 }
         *             }]
         *         };
         */
        return result;
    }

    private String decrypt(String encryptedDataStr, String keyBytesStr, String ivStr) {
        byte[] encryptedData;
        byte[] sessionKey;
        byte[] ivs;

        try {
            sessionKey = Base64.getDecoder().decode(keyBytesStr);
            encryptedData = Base64.getDecoder().decode(encryptedDataStr);
            ivs = Base64.getDecoder().decode(ivStr);

            SecretKeySpec skeySpec = new SecretKeySpec(sessionKey, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec iv = new IvParameterSpec(ivs);
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            byte[] original = cipher.doFinal(encryptedData);
            String originalString = new String(original, StandardCharsets.UTF_8);

            return originalString;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return "";
    }
    private ResponseResult getHistoryRecord(Map<String,Object> params){
        Map<String,Object> conditions=new HashMap<>();
        conditions.put("openId",params.get("openId"));
        conditions.put("tableName","weight_record");
        List<Map<String,Object>> records=commonDao.selectForMap(conditions);
        DateTimeFormatter formatter=DateTimeFormatter.ofPattern("yyyy-MM-dd");
        List<Map<String,Object>> data= records.stream().map(it -> {
            Map<String, Object> item = new HashMap<>();
            String dataString;
            if (it.get("date") instanceof Date) {
                LocalDateTime time = ((Date) it.get("date")).toInstant().atOffset(ZoneOffset.of("+8")).toLocalDateTime();
                dataString = time.format(formatter);
            } else {
                dataString = ((LocalDateTime) it.get("date")).format(formatter);
            }
            BigDecimal am = BigDecimal.valueOf(0);
            if (it.get("morning_weight") != null) {
                am = (BigDecimal) it.get("morning_weight");
            }
            BigDecimal pm = BigDecimal.valueOf(0);
            if (it.get("afternoon_weight") != null) {
                pm = (BigDecimal) it.get("afternoon_weight");
            }
            item.put("date", dataString);
            item.put("am", am);
            item.put("pm", pm);
            return item;
        }).sorted((a, b) -> b.get("date").toString().compareTo(a.get("date").toString())).collect(Collectors.toList());
        ResponseResult result=new ResponseResult();
        result.setCode(200);
        Map<String,Object> recordData=new HashMap<>();
        recordData.put("record",data);
        result.setData(recordData);
        return result;
    }
    private ResponseResult getHomeData(Map<String,Object> params){
        ResponseResult result=new ResponseResult();
        result.setCode(200);
        Map<String,Object> data=new HashMap<>();
        Map<String,Object> mainData=getExecDays(params);
        data.put("days",mainData.get("days"));
        data.put("yesterday",mainData.get("yesterday"));
        data.put("today",mainData.get("today"));
        data.put("minValue",mainData.get("minValue"));
        data.put("maxValue",mainData.get("maxValue"));
        String[] sports={"未获取","未获取"};
        data.put("sports",sports);
        Map<String,Object> homeData=new HashMap<>();
        homeData.put("homeData",data);
        homeData.put("swiperItems",getSwiperItems(params));
        result.setData(homeData);
        return result;
    }
    private Map<String,Object> getExecDays(Map<String,Object> params){
        Map<String,Object> map=new HashMap<>();
        ArrayList data=new ArrayList();
        User user=userService.selectByOpenId(params.get("openId").toString());
        long sumDays=user.getBeginDate().toLocalDate().until(LocalDateTime.now(ZoneOffset.of("+8")).toLocalDate(), ChronoUnit.DAYS);
        Map<String,Object> conditions=new HashMap<>();
        conditions.put("openId",params.get("openId"));
        conditions.put("tableName","weight_record");
        List<Map<String,Object>> signDays=commonDao.selectForMap(conditions);
        if(signDays!=null){
            //signDays.sort(Comparator.comparing(e->(Date)e.get("date"));
            signDays.sort((o1, o2) -> o2.get("date").toString().compareTo(o1.get("date").toString()));
            long sign = signDays.stream()
                    .filter(it->!convertToLocalDateTime(it.get("date"))
                            .isBefore(user.getBeginDate())).count();
            LocalDateTime max=signDays.stream().
                    filter(it->it.get("date")!=null)
                    .map(it->convertToLocalDateTime(it.get("date")))
                    .max((e1,e2)->e1.isAfter(e2)?1:0).orElse(LocalDateTime.now(ZoneOffset.of("+8")));
            LocalDate tempDate=max.toLocalDate();
            long line=0;
            for (Map<String, Object> it : signDays) {
                LocalDateTime dateTime = convertToLocalDateTime(it.get("date"));
                if (tempDate.compareTo(dateTime.toLocalDate()) == 0) {
                    line++;
                }else {
                    break;
                }
                tempDate = tempDate.minusDays(1);
            }
            data.add(sumDays);
            data.add(sign);
            data.add(line);
        }
        Map<String,Object> yesterday=signDays.stream()
                .filter(it->convertToLocalDateTime(it.get("date")).toLocalDate().isEqual(LocalDate.now(ZoneOffset.of("+8")).minusDays(1)))
                .findAny().orElse(null);
        Map<String,Object> today=signDays.stream()
                .filter(it->convertToLocalDateTime(it.get("date")).toLocalDate().isEqual(LocalDate.now(ZoneOffset.of("+8"))))
                .findAny().orElse(null);
        List<BigDecimal> amData= signDays.stream().map(it->{
            BigDecimal weight=BigDecimal.valueOf(0);
            if(it.get("morning_weight") != null){
                weight=(BigDecimal)it.get("morning_weight");
            }
            return weight;
        }).collect(Collectors.toList());
        List<BigDecimal> pmData= signDays.stream().map(it->{
            BigDecimal weight=BigDecimal.valueOf(0);
            if(it.get("afternoon_weight") != null){
                weight=(BigDecimal)it.get("afternoon_weight");
            }
            return weight;
        }).collect(Collectors.toList());
        BigDecimal amMinValue = amData.stream().filter(it->BigDecimal.valueOf(0).compareTo(it)<0).min(Comparator.naturalOrder()).orElse(BigDecimal.ZERO);
        BigDecimal amMaxValue = amData.stream().filter(it->BigDecimal.valueOf(0).compareTo(it)<0).max(Comparator.naturalOrder()).orElse(BigDecimal.ZERO);
        BigDecimal pmMinValue = pmData.stream().filter(it->BigDecimal.valueOf(0).compareTo(it)<0).min(Comparator.naturalOrder()).orElse(BigDecimal.ZERO);
        BigDecimal pmMaxValue = pmData.stream().filter(it->BigDecimal.valueOf(0).compareTo(it)<0).max(Comparator.naturalOrder()).orElse(BigDecimal.ZERO);
        ArrayList y=new ArrayList();
        ArrayList t=new ArrayList();
        ArrayList min=new ArrayList();
        ArrayList max=new ArrayList();
        min.add(amMinValue);
        min.add(pmMinValue);
        max.add(amMaxValue);
        max.add(pmMaxValue);

        setWeight(y,yesterday);
        setWeight(t,today);
        map.put("yesterday",y);
        map.put("today",t);
        map.put("days",data);
        map.put("minValue",min);
        map.put("maxValue",max);
        return map;
    }
    private void setWeight(ArrayList targetDay,Map<String,Object> sourceDay){
        if(sourceDay!=null) {
            targetDay.add(sourceDay.get("morning_weight")==null?"未记录":sourceDay.get("morning_weight"));
            targetDay.add(sourceDay.get("afternoon_weight")==null?"未记录":sourceDay.get("afternoon_weight"));
        }else {
            targetDay.add("未记录");
            targetDay.add("未记录");
        }
    }
    private List<Map<String,Object>> getSwiperItems(Map<String,Object> params){
        List<Map<String,Object>> data=new ArrayList<>();
        Map<String,Object> conditions=new HashMap<>();
        conditions.put("openId",params.get("openId"));
        conditions.put("tableName","swiper_items");
        List<Map<String,Object>> images=commonDao.selectForMap(conditions);
        if(images==null||images.size()<=0){
            Map<String,Object> map=new HashMap<>();
            map.put("id",1);
            map.put("path","../../images/misc/lake.jpg");
            map.put("url","");
            data.add(map);
        }else {
            data=images;
        }
        return data;
    }


    private LocalDateTime convertToLocalDateTime(Object date){
        if(date instanceof LocalDateTime){
            return (LocalDateTime)date;
        }
        if(date instanceof Date){
            Instant instant=((Date) date).toInstant();
            //instant.atZone(ZoneId.systemDefault()).toLocalDateTime();
            return instant.atOffset(ZoneOffset.of("+8")).toLocalDateTime();
        }
        return LocalDateTime.MIN;
    }

    /**
     * 获取时间戳
     * @return
     */
    private String getLocalDateTime(){
        return String.valueOf(LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")));
    }
    /**
     * 文本消息
     * @param requestMessage
     * @return
     */
    private String getTextMessage(RequestMessage requestMessage){
        TextMessage message=new TextMessage();
        message.setToUserName(requestMessage.getFromUserName());
        message.setFromUserName(requestMessage.getToUserName());
        message.setMsgType("text");
        message.setCreateTime(getLocalDateTime());
        message.setContent(requestMessage.getContent());
        return MyConvert.beanToXml(message,TextMessage.class);
    }
    private String getImageMessage(RequestMessage requestMessage){
        ImageMessage message=new ImageMessage();
        message.setToUserName(requestMessage.getFromUserName());
        message.setFromUserName(requestMessage.getToUserName());
        message.setMsgType("image");
        message.setCreateTime(getLocalDateTime());
        CommonSubMessage myImage= new CommonSubMessage();
        myImage.setMediaId(requestMessage.getMediaId());
        message.setImage(myImage);
        return MyConvert.beanToXml(message,ImageMessage.class);
    }
    private String getVoiceMessage(RequestMessage requestMessage){
        VoiceMessage message=new VoiceMessage();
        message.setToUserName(requestMessage.getFromUserName());
        message.setFromUserName(requestMessage.getToUserName());
        message.setMsgType("voice");
        message.setCreateTime(getLocalDateTime());
        CommonSubMessage voice= new CommonSubMessage();
        voice.setMediaId(requestMessage.getMediaId());
        message.setVoice(voice);
        return MyConvert.beanToXml(message,VoiceMessage.class);
    }
    private String getVideoMessage(RequestMessage requestMessage){
        sendNoticeMessage(requestMessage);
        ViedoMessage message=new ViedoMessage();
        message.setToUserName(requestMessage.getFromUserName());
        message.setFromUserName(requestMessage.getToUserName());
        message.setMsgType("video");
        message.setCreateTime(getLocalDateTime());
        CommonSubMessage video= new CommonSubMessage();
        video.setMediaId(requestMessage.getMediaId());
        video.setTitle("好看的视频");
        video.setDescription("给你说了好看的视频，你自己发的难道不好看，不好看你会发");
        message.setVideo(video);
        return MyConvert.beanToXml(message,ViedoMessage.class);
    }
    private String getMusicMessage(RequestMessage requestMessage){
        MusicMessage message=new MusicMessage();
        message.setToUserName(requestMessage.getFromUserName());
        message.setFromUserName(requestMessage.getToUserName());
        message.setMsgType("music");
        message.setCreateTime(getLocalDateTime());
        CommonSubMessage music= new CommonSubMessage();
        music.setThumbMediaId(requestMessage.getMediaId());
        message.setMusic(music);
        return MyConvert.beanToXml(message,MusicMessage.class);
    }
    private String getShortVideoMessage(RequestMessage requestMessage){
        return "";
    }
    private String getLocationMessage(RequestMessage requestMessage){
        return "";
    }
    private String getLinkMessage(RequestMessage requestMessage){
        return "";
    }
    private String getEventMessage(RequestMessage requestMessage) {
        String resultXml;
        switch (requestMessage.getEvent()) {
            case "subscribe"://添加关注/未关注扫码
                if(!StringUtils.isEmpty(requestMessage.getEventKey())&&requestMessage.getEventKey().contains("qrscene")){
                    //扫码关注
                }else {
                    //关注
                }
                resultXml="";
                break;
            case "unsubscribe"://取消关注
                resultXml="";
                break;
            case "SCAN"://关注后扫描
                resultXml="";
                break;
            case "LOCATION"://上报地理位置
                resultXml="";
                break;
            case "CLICK"://用户点击
                resultXml = getClickMessage(requestMessage);
                break;
            case "VIEW":
                resultXml="";
                break;
            default:
                resultXml = "";
                break;
        }
        return resultXml;
    }
    private String getClickMessage(RequestMessage requestMessage){
        String resultXml;
        switch (requestMessage.getEventKey()) {
            case "OrderQuery":
                TextMessage message=new TextMessage();
                message.setToUserName(requestMessage.getFromUserName());
                message.setFromUserName(requestMessage.getToUserName());
                message.setMsgType("text");
                message.setCreateTime(getLocalDateTime());
                message.setContent("这个需要自己摸索了");
                resultXml = MyConvert.beanToXml(message,TextMessage.class);
                break;
            case "DayQuery":
                GraphicMessage graphicMessage=new GraphicMessage();
                graphicMessage.setToUserName(requestMessage.getFromUserName());
                graphicMessage.setFromUserName(requestMessage.getToUserName());
                graphicMessage.setMsgType("news");
                graphicMessage.setCreateTime(getLocalDateTime());
                graphicMessage.setArticleCount("1");
                GraphicMiddleMessage middleMessage=new GraphicMiddleMessage();
                GraphicSubMessage subMessage = new GraphicSubMessage();
                subMessage.setTitle("今日特惠");
                subMessage.setDescription("今天优惠多的不得了，可惜您来晚了！");
                subMessage.setPicUrl("http://k316227949.eicp.net/Image/image.jpg");
                subMessage.setUrl("https://www.lamajihua.com/lamashop/index?lamaid=6090edc7c7ba4e14b00a80b31b3c6f6a&from=singlemessage");
                middleMessage.getItem().add(subMessage);
                graphicMessage.setArticles(middleMessage);
                resultXml = MyConvert.beanToXml(graphicMessage,GraphicMessage.class);
                break;
            default:
                resultXml = "";
                break;
        }
        return resultXml;
    }

    private void sendNoticeMessage(RequestMessage requestMessage){
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(type);
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
        Map<String,Object> map=getJsonMap(requestMessage);
        ObjectMapper objectMapper = new ObjectMapper();
        HttpEntity<String> formEntity = null;
        try {
            formEntity = new HttpEntity<>(objectMapper.writeValueAsString(map), headers);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        String tempUrl="https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s";

        tempUrl = String.format(tempUrl, getAccessToken());
        try {
            restTemplate.postForObject(tempUrl, formEntity, String.class);
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }
    private String getAccessToken() {
        String token;
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
        url = String.format(url, "wx88364778ceae4f80", "06d8c16f54c183f478f6140ab7a85a3c");
        Map map = restTemplate.getForObject(url, Map.class);
        token = map.get("access_token").toString();
        return token;
    }
    private Map<String,Object> getJsonMap(RequestMessage requestMessage){
        Map<String,Object> mapMain=new HashMap<>();
        mapMain.put("touser", requestMessage.getFromUserName());
        mapMain.put("template_id", "b1uwtZdiPHMiqQS9NZySlVWedqVJfsZVfc_3lz7YrJU");
        Map<String,Object> data = new HashMap<>();
        Map<String,Object> items = new HashMap<>();
        items.put("value", "您发送了视频");
        items.put("color", "#173177");
        data.put("billType", items);
        items = new HashMap<>();
        items.put("value", requestMessage.getMsgId());
        items.put("color", "#173177");
        data.put("billNo", items);
        items = new HashMap<>();
        items.put("value", LocalDateTime.now(ZoneOffset.of("+8")).format(DateTimeFormatter.ofPattern(("yyyy-MM-dd"))));
        items.put("color", "#173177");
        data.put("submitTime", items);
        items = new HashMap<>();

         items.put("value", requestMessage.getFromUserName());
         items.put("color", "#173177");

        data.put("creater", items);
        items = new HashMap<>();
        items.put("value", "看上去不错");
        items.put("color", "#173177");

        data.put("remark", items);
        mapMain.put("data", data);

        return mapMain;
    }
    private void saveUser(RequestMessage requestMessage){

    }
    public static void main(String[] args) {
        LocalDateTime beginDate=LocalDateTime.of(2020,3,12,00,0);
        LocalDateTime dateTime=LocalDateTime.now(ZoneOffset.of("+8"));
        LocalDateTime dateTime1 = LocalDateTime.now();
        LocalDate date=LocalDate.now();
        LocalTime time = LocalTime.now();
        long sumDays=beginDate.toLocalDate().until(LocalDateTime.now().toLocalDate(), ChronoUnit.DAYS);
        System.out.println(sumDays);
    }
}


